package tech.aistar.day13;

/**
 * 本类用来演示: 自定义注解
 *
 * @author: success
 * @date: 2022/8/4 1:47 下午
 */

import java.lang.annotation.*;
import java.lang.reflect.Method;

//该注解可以被应用的位置 - 类/接口 以及 方法上都是允许的
@Target({ElementType.TYPE,ElementType.METHOD})
//注解的保持策略 - 此处设置成运行时,在运行期间可以通过反射的技术来操作注解.
@Retention(RetentionPolicy.RUNTIME)
@Inherited //注解是否允许被继承
public @interface MyAnno {

    //如果属性名是value - 默认的
    String value(); //注解中只有属性的概念,没有方法的概念.

    //允许出现多个属性
    int age();
}

//@MyAnno("admin") //如果属性是value,那么此处value单词是可以省略不写的
//如果有俩个属性的话,那么在使用的时候,value也是不允许省略
@MyAnno(value = "admin", age = 18) //如果属性是value,那么此处value单词是可以省略不写的
class AnnoApp{

    @MyAnno(value = "tom",age=20)
    public void test(){
        System.out.println("test()...");
    }
}

//反射获取注解的相关信息
//拿到AnnoApp注解
class AnnoTest{
    public static void main(String[] args) {
        //1. 获取注解的class实例
        Class<?> c = AnnoApp.class;

        //2. 判断该类上是否加了注解
        if(c.isAnnotationPresent(MyAnno.class)){
            System.out.println("加了注解!");

            //AnnoApp类上的注解的对象
            MyAnno anno = c.getDeclaredAnnotation(MyAnno.class);

            //因为注解中存在俩个属性
            System.out.println(anno.age());

            System.out.println(anno.value());

        }else{
            System.out.println("没有加注解!");
        }


        //3. 获取方法上注解的相关属性信息
        //1. 方法对应的method实例
        try {
            Method m = c.getDeclaredMethod("test");

            //判断这个方法上是否添加了注解
            if(m.isAnnotationPresent(MyAnno.class)){

                //获取该注解的对象
                MyAnno myAnno = m.getAnnotation(MyAnno.class);
                System.out.println(myAnno.value());
                System.out.println(myAnno.age());
            }

        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}